﻿module Lhz.Page {
    export class ManagementPage<T extends Lhz.Entity.ServiceCenter.DbEntity> extends Page {
        options: Lhz.Interface.Page.ManagementPageOptions<T>;
        private $table: any;
        sci = new Lhz.ServiceCenter.Invoker();
        private items: T[];

        constructor(options: Lhz.Interface.Page.ManagementPageOptions<T>) {
            super();
            if (this.indexInitialized) {
                this.options = $.extend({
                    dbOperation: true,
                    tableSelector: ".management-table",
                    queryOperationNo: "query",
                    deleteOperationNo: "deleteByPks",
                    buttonAddSelector: "#buttonAdd",
                    addOperationName: "新增",
                    editOperationName: "编辑",
                    deleteOperationName: "删除",
                    buttonEditSelector: "#buttonEdit",
                    buttonDeleteSelector: "#buttonDelete"
                }, options);
                if (!this.options.getQueryArguments) {
                    this.options.getQueryArguments = function (mp) {
                        return [null];
                    };
                }
                if (!this.options.getDeleteArguments) {
                    this.options.getDeleteArguments = function (mp, e) {
                        var pks: string[] = [];
                        for (var selection of mp.getSelections()) {
                            pks.push(selection.item.Guid);
                        }
                        return [pks];
                    };
                }
                if (!this.options.getDetailArguments) {
                    this.options.getDetailArguments = function (mp, selectedItem) {
                        return {
                            item: selectedItem,
                            dbOperation: mp.options.dbOperation
                        };
                    };
                }
                this.mpInitiate();
            }
        }

        private mpInitiate() {
            this.$table = $(this.options.tableSelector);
            this.buildButton();
            this.buildTable();

            if (this.options.initiate) {
                this.options.initiate(this, function (mp) {
                    mp.mpInitiating();
                });
            }
            else {
                this.mpInitiating();
            }
        }

        private mpInitiating() {
            if (this.options.dbOperation) {
                this.query(function (mp) {
                    mp.mpInitialized();
                });
            }
            else {
                if (this.options.data) {
                    this.items = this.options.data;
                }
                else {
                    this.items = [];
                }
                this.mpInitialized();
            }
        }

        private mpInitialized() {
            this.show();
            if (this.options.initialized) {
                this.options.initialized(this);
            }
        }

        private buildButton() {
            $(this.options.buttonAddSelector).button({ icons: { primary: "ui-icon-plusthick" } }).click(this, function (event) {
                var mp: ManagementPage<T> = event.data;
                mp.add();
            });
            $(this.options.buttonEditSelector).button({ icons: { primary: "ui-icon-minusthick" } }).click(this, function (event) {
                var mp: ManagementPage<T> = event.data;
                var selections = mp.getSelections();
                if (selections.length == 0) {
                    alert("请选择操作对象。");
                }
                else if (selections.length == 1) {
                    mp.edit(selections[0].item);
                }
                else if (selections.length > 1) {
                    alert("该操作暂不支持多选。");
                }
                else {
                    throw "选择记录个数【" + selections.length + "】异常。";
                }
            });
            $(this.options.buttonDeleteSelector).button({ icons: { primary: "ui-icon-closethick" } }).click(this, function (event) {
                var mp: ManagementPage<T> = event.data;
                var selections = mp.getSelections();
                if (selections.length == 0) {
                    alert("请选择操作对象。");
                }
                else {
                    var selectedItems: T[] = [];
                    for (var selection of selections) {
                        selectedItems.push(selection.item);
                    }
                    if (mp.options.deleteCheck) {
                        mp.showLoading();
                        mp.options.deleteCheck(mp, selectedItems, function (names: string[]) {
                            mp.closeLoading();
                            if (names.length == 0) {
                                mp.delete(selectedItems);
                            }
                            else {
                                alert("应用【" + names.join(",") + "】不允许删除，要删除的应用不能包含任何服务。");
                            }
                        });
                    }
                    else {
                        mp.delete(selectedItems);
                    }
                }
            });
        }

        private buildTable() {
            var mp = this;
            this.$table = this.$table.pqGrid({
                title: this.options.targetName + "列表",
                editable: false,
                width: "100%",
                height: "100%",
                colModel: this.options.colModel,
                rowDblClick: function (event, selection) {
                    var selectedItem: T = selection.dataModel.data[selection.rowIndx];
                    mp.edit(selectedItem);
                }
            });
        }

        query(queryCallback: (mp: ManagementPage<T>) => void = function (mp) { mp.show(); }) {
            super.showLoading();
            this.sci.InvokeByInvokeArgument<T[]>({
                serviceNo: this.options.serviceNo,
                operationNo: this.options.queryOperationNo,
                arguments: this.options.getQueryArguments(this),
                successCallback: function (result, data) {
                    var mp: ManagementPage<T> = data;
                    mp.closeLoading();
                    mp.items = result.Result;
                    queryCallback(mp);
                },
                data: this
            });
        }

        private show() {
            this.$table.pqGrid("option", "dataModel.data", this.items);
        }

        private add() {
            super.showDialog({
                url: this.options.detailPageUrl,
                width: this.options.width,
                height: this.options.height,
                title: this.options.addOperationName + this.options.targetName,
                arguments: this.options.getDetailArguments(this, null),
                dialogClosed: function (returnValue: T, mp: ManagementPage<T>) {
                    if (returnValue) {
                        if (mp.options.dbOperation) {
                            mp.query();
                        }
                        else {
                            mp.items.push(returnValue);
                            mp.show();
                        }
                    }
                },
                data: this
            });
        }

        getSelections(): { index: number, item: T }[] {
            var selections: { index: number, item: T }[] = [];
            var pqSelections = this.$table.pqGrid("selection", { type: "row", method: "getSelection" });
            for (var pqSelection of pqSelections) {
                selections.push({ index: pqSelection, item: this.items[pqSelection.rowIndx] });
            }
            return selections;
        }

        private edit(selectedItem: T) {
            super.showDialog({
                url: this.options.detailPageUrl,
                width: this.options.width,
                height: this.options.height,
                title: this.options.editOperationName + this.options.targetName + "【" + this.options.getItemName(this, selectedItem) + "】",
                arguments: this.options.getDetailArguments(this, selectedItem),
                dialogClosed: function (returnValue: T, mp: ManagementPage<T>) {
                    if (returnValue) {
                        if (mp.options.dbOperation) {
                            mp.query();
                        }
                        else {
                            mp.show();
                        }
                    }
                },
                data: this
            });
        }

        private delete(selectedItems: T[]) {
            var names: string[] = [];
            for (var selectedItem of selectedItems) {
                names.push(this.options.getItemName(this, selectedItem));
            }
            if (confirm("确认" + this.options.deleteOperationName + "【" + names.join(",") + "】" + selectedItems.length + "个" + this.options.targetName + "？")) {
                if (this.options.dbOperation) {
                    this.showLoading();
                    if (this.options.childrenDeleteServiceNos == null && this.options.childrenDeleteOperationNos == null && this.options.getChildrenDeleteArgumentsList == null) {
                        this.sci.InvokeByInvokeArgument({
                            serviceNo: this.options.serviceNo,
                            operationNo: this.options.deleteOperationNo,
                            arguments: this.options.getDeleteArguments(this, selectedItems),
                            successCallback: function (result, mp: ManagementPage<T>) {
                                mp.closeLoading();
                                alert(mp.options.deleteOperationName + "成功。");
                                mp.query();
                            },
                            data: this
                        });
                    }
                    else {
                        var serviceNos: string[] = [this.options.serviceNo];
                        var operationNos: string[] = [this.options.deleteOperationNo];
                        var argumentsList: any[][] = [this.options.getDeleteArguments(this, selectedItems)];
                        for (var childDeleteServiceNo in this.options.childrenDeleteServiceNos) {
                            serviceNos.push(childDeleteServiceNo);
                        }
                        for (var childDeleteOperationNo in this.options.childrenDeleteOperationNos) {
                            operationNos.push(childDeleteOperationNo);
                        }
                        for (var childDeleteArguments in this.options.getChildrenDeleteArgumentsList(this, selectedItems)) {
                            argumentsList.push(childDeleteArguments);
                        }
                        this.sci.InvokeByInvokeArguments({
                            serviceNos: serviceNos,
                            operationNos: operationNos,
                            argumentsList: argumentsList,
                            successCallback: function (result, mp: ManagementPage<T>) {
                                mp.closeLoading();
                                alert(mp.options.deleteOperationName + "成功。");
                                mp.query();
                            },
                            data: this
                        });
                    }
                }
                else {
                    for (var selectedItem of selectedItems) {
                        this.items.splice(this.items.indexOf(selectedItem), 1);
                    }
                    this.show();
                }
            }
        }
    }
}
